import { Component, Host, h, Prop, Element, forceUpdate } from '@stencil/core';
import { MicroApp } from 'qiankun';
import { AppStatus } from '../../interface/micro.interface';
import { loadQueueApp } from '../../utils/micro.util';
import { getAscendingId } from '../../global';
import { BehaviorSubject } from 'rxjs';

const cacheData = {};

@Component({
  tag: 'ds-micro-qiankun',
  styleUrl: 'ds-micro-qiankun.css',
  shadow: false,
})
export class DsMicroQiankun {
  /** 加载页面的域名 */
  @Prop() host!: string;

  @Prop() cacheKey: string;

  /** 给子应用的数据 */
  @Prop() data: BehaviorSubject<any>;

  /** 宿主元素 */
  @Element() el: HTMLElement;
  /** 加载的微前端容器元素 */
  microContainer: HTMLElement;

  /** 全局唯一id */
  id = getAscendingId();

  /** 子应用实例 */
  microApp: MicroApp = null;

  /** 是否是第一次加载 */
  isFirst = true;

  /** 子应用状态——与qiankun应用状态互补 */
  status = null;

  getReplaceUrl(url: string) {
    return url + this.cacheKey ? (url + this.cacheKey).replace(/https:\/\/|http:\/\//, '').replace(/\/|\-|\:|\./g, '_') : '';
  }

  /** 组件加载 */
  componentDidLoad() {
    if (!this.cacheKey) {
      this.cacheKey = '/' + this.id;
    }
    if (!this.host) {
      return;
    }
    console.log('--------------------------', this.cacheKey, cacheData);
    if (cacheData[this.getReplaceUrl(this.host)]) {
      this.id = cacheData[this.getReplaceUrl(this.host)].id;
      // this.microApp = cacheData[this.getReplaceUrl(this.host)].microApp;
      // this.el.appendChild(cacheData[this.getReplaceUrl(this.host)].el);
      forceUpdate(this.el);
      // setTimeout(() => {
      //   this.appMount();
      // });
      // return;
    }
    console.log(this.id, '组件id');
    loadQueueApp(
      this.host,
      {
        opt: {
          name: this.id,
          entry: this.host,
          container: document.getElementById(this.id),
          props: {
            systemData: new BehaviorSubject({
              id: this.id,
              host: this.host,
            }),
            data: this.data,
          },
        },
        config: {
          sandbox: {
            strictStyleIsolation: false,
            experimentalStyleIsolation: true,
          },
          fetch: (url, ...args) => {
            return window.fetch(url, ...args);
          },
          getTemplate: (tpl: string) => {
            return tpl;
          },
        },
      },
      v => {
        this.microApp = v;
        this.isFirst = false;
        this.status = this.getStatus();
        console.log('初始化子应用:');
      },
    );
  }

  // 获取现在的qiankun组件状态
  getStatus() {
    return AppStatus[this.microApp.getStatus()];
  }

  /** 组件连接文档 */
  connectedCallback() {
    if (this.isFirst) {
      return;
    }
    if (!this.microApp) {
      return;
    }
    this.appMount();
  }

  /** 组件卸载 */
  disconnectedCallback() {
    if (!this.host) {
      this.el.remove();
      return;
    }
    // let cloneNode = null;
    if (cacheData[this.getReplaceUrl(this.host)] && cacheData[this.getReplaceUrl(this.host)].el) {
      // cloneNode = cacheData[this.getReplaceUrl(this.host)].el.cloneNode(true);
    }
    cacheData[this.getReplaceUrl(this.host)] = {
      id: this.id,
      // microApp: this.microApp,
      // el: cloneNode ? cloneNode.cloneNode(true) : this.el.cloneNode(true),
    };

    setTimeout(() => {
      this.appUnMount();
    });
  }

  /**qiannkun 应用加载 */
  appMount() {
    if (!this.microApp) {
      return;
    }
    this.status = this.getStatus();
    const canMount = [AppStatus.NOT_MOUNTED] as any;
    if (!canMount.includes(this.status)) {
      return;
    }
    this.microApp.mount().then(v => {
      console.log('子应用加载, ', v, this.id);
      if (this.status === AppStatus.NOT_MOUNTED) {
        // this.appUnMount();
      }
    });
  }

  /**qiannkun 应用卸载 */
  appUnMount() {
    if (!this.microApp) {
      return;
    }
    this.status = this.getStatus();
    const canUnMount = [AppStatus.MOUNTED, AppStatus.MOUNTING] as any;
    if (!canUnMount.includes(this.status)) {
      return;
    }
    this.microApp.unmount().then(() => {
      console.log('子应用卸载, ', this.id);
      if (this.status === AppStatus.MOUNTED) {
        // this.appMount();
      }
    });
  }

  render() {
    return (
      <Host id={this.id}>
        <div ref={el => (this.microContainer = el)}></div>
      </Host>
    );
  }
}
